﻿using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace GISDeveloping_test4
{

    /// <summary>
    /// 用于进行空间查询的窗体
    /// </summary>
    public partial class ShowFeatureInfo : Form
    {
        IHookHelper hookHelper;
        AxMapControl axMapControl1;
        EnumSelectType actionFlag;
        IFeatureLayer pFeatureLayer;
        IMap map;
        int mouseX;
        int mouseY;
        IGeometry selectedGeometry;
        int currentFeatureIndex = -1;
        IEnumFeature m_enumFeature;
        IFeature currentFeature;
        IFeatureLayer selectedLayer;
        IFeatureSelection m_featureSelection;
        ICursor m_cursor;
        IFeatureCursor m_featureCursor;




        public ShowFeatureInfo(IHookHelper m_hookHelper)
        {
            InitializeComponent();
            hookHelper = m_hookHelper;
            axMapControl1 = Control.FromHandle(new IntPtr(this.hookHelper.ActiveView.ScreenDisplay.hWnd)) as AxMapControl;
            map = hookHelper.FocusMap;
            //设定RadioButton的初始值
            PointSelectButton.Checked = true;
            actionFlag = EnumSelectType.POINTSELECT;
        }

        private void ShowFeatureInfo_Load(object sender, EventArgs e)
        {
            //设置dataGridView1的列数和列标题
            dataGridView1.ColumnCount = 2;
            dataGridView1.RowHeadersWidth = 60;
            dataGridView1.TopLeftHeaderCell.Value = "序号";
            dataGridView1.Columns[0].HeaderText = "字段";
            dataGridView1.Columns[1].HeaderText = "属性值";
            cbxAddLayer();
        }



        /// <summary>
        /// 向ComboBox中添加图层名
        /// </summary>
        public void cbxAddLayer()
        {
            if (GetLayers() == null) return;
            IEnumLayer layers = GetLayers();
            layers.Reset();
            ILayer layer = null;
            while ((layer = layers.Next()) != null)
            {
                if (layer is IFeatureLayer)
                    LayerComboBox.Items.Add(layer.Name);
            }

            //设置第一个图层为默认选项
            if (LayerComboBox.Items.Count > 0)
            {
                LayerComboBox.SelectedIndex = 0;
            }
        }



        /// <summary>
        /// 获取map中的所有图层
        /// </summary>
        /// <returns></returns>
        private IEnumLayer GetLayers()
        {

            if (map.LayerCount == 0)
            {
                return null;
            }
            return map.Layers;
        }


        public void SpatialQuery(int X, int Y)
        {
            mouseX = X;
            mouseY = Y;
            selectedGeometry = GetSelectGeo(X, Y);
        }


        /// <summary>
        /// 通过图层下拉列表选择待查询的图层
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (LayerComboBox.Items.Count == 0)
            {
                return;
            }
            // 获取所选图层
            selectedLayer = GetFeatureLayer(LayerComboBox.Text);
        }




        /// <summary>
        /// 生成缓冲区
        /// </summary>
        /// <param name="X"></param>
        /// <param name="Y"></param>
        /// <returns></returns>
        public IGeometry CreateBuffer(int X, int Y)
        {
            IPoint pMouseDownPoint;
            //有两种方式可获取地图上的坐标点
            //pMouseDownPoint = axMapControl.ToMapPoint(e.x, e.y);
            pMouseDownPoint = axMapControl1.ToMapPoint(X, Y);
            pMouseDownPoint.SpatialReference = hookHelper.FocusMap.SpatialReference;
            IGeometry bufGeo;
            ITopologicalOperator bufferPoint = pMouseDownPoint as ITopologicalOperator;
            bufGeo = bufferPoint.Buffer(hookHelper.ActiveView.Extent.Width / 250);
            return bufGeo;
        }




        /// <summary>
        /// 向dataGridView中添加属性数据
        /// </summary>
        /// <param name="feature"></param>
        public void ShowAttribute(IFeature feature)
        {
            //将列数量设置为字段数
            int num = feature.Fields.FieldCount;
            dataGridView1.RowCount = num;
            int i = 0;
            for (i = 0; i < num; i++)
            {
                //填充行号与行标题
                dataGridView1.Rows[i].HeaderCell.Value = i.ToString();
                dataGridView1[0, i].Value = feature.Fields.get_Field(i).Name.ToString();

                //填充字段
                if (feature.Fields.get_Field(i).Type == esriFieldType.esriFieldTypeGeometry)
                {
                    string type = feature.Shape.GeometryType.ToString();
                    switch (type)
                    {
                        case "esriGeometryPoint":
                            dataGridView1[1, i].Value = "点";
                            break;
                        case "esriGeometryPolyline":
                            dataGridView1[1, i].Value = "线";
                            break;
                        case "esriGeometryPolygon":
                            dataGridView1[1, i].Value = "面";
                            break;
                    }
                }
                else
                {
                    if (feature.Value[i] != null)
                        dataGridView1[1, i].Value = feature.Value[i].ToString();
                    else
                        dataGridView1[1, i].Value = "";
                }
            }
            this.toolStripStatusLabel1.Text = "查询的要素共有" + feature.Fields.FieldCount.ToString() +
                "个字段";
        }



        /// <summary>
        /// 选择方式
        /// </summary>
        public enum EnumSelectType : int
        {
            //点选
            POINTSELECT = 1,
            //圈选
            CIRCLESELECT = 2,
            //框选
            RECTSELECT = 3,
            //多边形选择
            POLYGONSELECT = 4
        }




        /// <summary>
        /// 获取axMapControl中被选中的要素
        /// </summary>
        /// <param name="X"></param>
        /// <param name="Y"></param>
        /// <returns></returns>
        public IGeometry GetSelectGeo(int X, int Y)
        {
            axMapControl1.MousePointer = esriControlsMousePointer.esriPointerCrosshair;
            IGeometry geometry = null;

            switch (actionFlag)
            {
                case EnumSelectType.POINTSELECT:
                    //IPoint pt = new PointClass();
                    //pt = axMapControl1.ToMapPoint(X, Y);
                    geometry = CreateBuffer(X, Y);
                    break;
                case EnumSelectType.CIRCLESELECT:
                    geometry = axMapControl1.TrackCircle();
                    break;
                case EnumSelectType.RECTSELECT:
                    geometry = axMapControl1.TrackRectangle();
                    break;
                case EnumSelectType.POLYGONSELECT:
                    geometry = axMapControl1.TrackPolygon();
                    break;
            }
            return geometry;
        }




        /// <summary>
        /// 更改RadioButton的选择时发生，确保RadioButton为单选
        /// 调整actionFlag的值（选择模式），以便进行相应的选择
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void RadioButton_CheckedChanged(object sender, EventArgs e)
        {
            RadioButton selectedRadioButton = sender as RadioButton;
            if (selectedRadioButton != null && selectedRadioButton.Checked)
            {
                foreach (Control control in Controls)
                {
                    if (control is RadioButton radioButton && radioButton != selectedRadioButton)
                    {
                        radioButton.Checked = false;
                    }
                    if (selectedRadioButton == PointSelectButton)
                    {
                        actionFlag = EnumSelectType.POINTSELECT;
                    }
                    if (selectedRadioButton == RectSelectButton)
                    {
                        actionFlag = EnumSelectType.RECTSELECT;
                    }
                    if (selectedRadioButton == PolygonSelectButton)
                    {
                        actionFlag = EnumSelectType.POLYGONSELECT;
                    }
                    if (selectedRadioButton == CircleSelectButton)
                    {
                        actionFlag = EnumSelectType.CIRCLESELECT;
                    }
                }
            }
        }


        /// <summary>
        /// 根据图层名称返回FeatureLayer
        /// </summary>
        /// <param name="layername"></param>
        /// <returns></returns>
        public IFeatureLayer GetFeatureLayer(string layername)
        {
            if (GetLayers() == null)
                return null;
            IEnumLayer layers = GetLayers();
            layers.Reset();
            ILayer layer = null;
            while ((layer = layers.Next()) != null)
            {
                if (layer.Name == layername)
                    return layer as IFeatureLayer;
            }
            return null;
        }


        /// <summary>
        /// 执行空间查询按钮，当框选多个要素时，默认显示最后一个要素的属性表
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SpatialQueryButton_Click(object sender, EventArgs e)
        {
            IFeature feature1 = null;
            //pFeatureLayer = hookHelper.FocusMap.ActiveGraphicsLayer as IFeatureLayer;
            pFeatureLayer = GetFeatureLayer(LayerComboBox.Text);
            IFeatureSelection featureSelection = pFeatureLayer as IFeatureSelection;
            // 获取所选图层
            selectedLayer = GetFeatureLayer(LayerComboBox.Text);
            ISpatialFilter spatialFilter = new ESRI.ArcGIS.Geodatabase.SpatialFilterClass();
            spatialFilter.Geometry = selectedGeometry;
            spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
            IFeatureCursor featureCursor = null;

            try
            {
                featureCursor = selectedLayer.Search(spatialFilter, false);
                featureSelection.SelectFeatures(spatialFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
                IFeature pFeature = featureCursor.NextFeature();
                while (pFeature != null)
                {
                    
                    feature1 = pFeature;
                    pFeature = featureCursor.NextFeature();
                }
                //让显示在属性表中的要素闪烁
                if (feature1 != null)
                {
                    ShowAttribute(feature1);
                    axMapControl1.FlashShape(feature1.Shape);
                }

                /*
                不能从map.FeatureSelection获取FeatureSelection，因为这时获取的选择集是
                地图的选择集而非图层的选择集，这个选择集中包含了feature的shape属性和字段名
                但没有包含字段值
                */

                m_featureSelection = featureSelection;
                //获取FeatureSelection
                //ISelection selection = map.FeatureSelection;    //该语句可能出现问题，导致选择集的属性表无法被传递到 m_enumFeature中
                //从FeatureSelection获取enumFeature
                //m_enumFeature = selection as IEnumFeature;
                //m_enumFeature.Reset();
                //m_enumFeature = enumFeature;
            }


            //释放资源
            finally
            {
                //以下两种刷新方法均可
                //axMapControl1.Refresh(esriViewDrawPhase.esriViewGeoSelection, null, null);
                hookHelper.ActiveView.Refresh();
                //释放游标
                if (featureCursor != null)
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(featureCursor);
            }
        }



        /// <summary>
        /// 切换显示选择集中要素的属性
        /// <para>假设一次框选选中了10个要素，点击该按钮后能够显示这10个要素中下一个要素的属性</para>
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SwitchButton_Click(object sender, EventArgs e)
        {
            /* 
             * 从m_featureSelection获取feature：利用search方法得到cursor，将其转换到
             * featurecursor后使用m_featureCursor.NextFeature对featureselection中的
             * feature进行遍历
             */
            if (m_featureSelection != null)
            {
                if (m_cursor == null)
                {
                    m_featureSelection.SelectionSet.Search(null, false, out m_cursor);
                    m_featureCursor = (IFeatureCursor)m_cursor;
                }
                currentFeature = m_featureCursor.NextFeature();
                if (currentFeature == null)
                {
                    // 已经到达选择集的末尾，重新开始循环
                    m_featureSelection.SelectionSet.Search(null, false, out m_cursor);
                    // 将 ICursor 转换为 IFeatureCursor
                    m_featureCursor = (IFeatureCursor)m_cursor;
                    currentFeature = m_featureCursor.NextFeature();
                }
                ShowAttribute(currentFeature);
                axMapControl1.FlashShape(currentFeature.Shape);
            }

            //以下代码已弃用
            //if (m_enumFeature != null )
            //{

            //    IFeature feature = m_enumFeature.Next();

            //    if (feature != null)
            //    {
            //        ShowAttribute(feature);
            //        axMapControl1.FlashShape(feature.Shape);
            //    }
            //    else
            //    {
            //        // 重新开始循环
            //        m_enumFeature.Reset();
            //        currentFeature = null;
            //    }
            //}

        }



        
    }
}
